<template>
  <div class="com-box">
    <el-tabs
        v-model="activeName"
        class="demo-tabs"
        @tab-click="handleClick"
        type="border-card"
        style="width: 100%;"
    >

      <el-tab-pane label="本地上传" name="locally">
        <div class="button">
          <el-button type="primary" :disabled="fileListLocally.length<=0" @click="confirmSelection('locally')">确定使用</el-button>
        </div>
        <el-upload
            v-model:file-list="fileList"
            :action="uploadUrl"
            list-type="picture-card"
            :limit="uploadLimit"
            :drag="true"
            name="file"
            :multiple="true"
            :data="{path:path}"
            :on-exceed="goTooFar"
            :on-success="successUpload"
            :on-error="errorUpload"
            :before-remove = "beforeRemove"
        >
          <el-icon><Plus /></el-icon>
          <template #tip>
            <div class="el-upload__tip">
              最多可上传1张图片,可拖拽至+号位置上传
            </div>
          </template>
        </el-upload>
      </el-tab-pane>



      <el-tab-pane label="文件列表" name="online">
        <div class="button">
          <el-button type="primary" :disabled="fileListOnline.length<=0" @click="confirmSelection('online')">确定使用</el-button>
          <text>请选择图片，最多选择{{uploadLimit}}张图片</text>
        </div>
        <div class="picture-list">
          <div class="picture-box">
            <div
                v-for="(image, index) in imageArray"
                :key="index"
                class="image-wrapper"
                :class="{ 'selected': image.isSelected }"
                @mouseenter="image.isShowMask = true"
                @mouseleave="image.isShowMask = false"
            >
              <el-image
                  style="width: 100px; height: 100px;"
                  :src="image.src"
                  fit="contain"
                  @click="toggleSelect(image)"
              />
              <div v-if="image.isShowMask" class="mask">
                <el-icon class="delete-icon" @click.stop="deleteImage(index)"><DeleteFilled /></el-icon>
              </div>
              <div v-if="image.isSelected" class="check-mark">
                <el-icon><Check /></el-icon>
              </div>
            </div>
          </div>
        </div>
      </el-tab-pane>

    </el-tabs>
  </div>
</template>

<script setup>
import {computed, getCurrentInstance, onMounted, ref} from 'vue'
import {Plus} from '@element-plus/icons-vue'
import {showMessage} from '@/utils/message';
import {getFileArray} from "@/http/common";

//服务端地址
const requestUrl = process.env.VUE_APP_REQUEST_URL;
const {proxy} = getCurrentInstance();
/**
 * 在此定义，我们需要从引用组件的页面拿到limit参数，确定本次最多可以上传多少张
 * @type {Prettify<Readonly<ExtractPropTypes<{uploadLimit: {default: number, type: NumberConstructor}}>>>}
 */
const props = defineProps({
  uploadLimit: {
    type: Number,
    default: 1 // 默认值为 1
  },
  path:{
    type: String,
  }
});
const activeName = ref('locally')
//上传接口地址
const uploadUrl = requestUrl + "/backstage/backUpload"
//切换tabs
const handleClick = (tab) => {
  activeName.value = tab.props.name;
}
const fileList = ref([]);
//上传图片的数组,返回给父组件使用
const fileListLocally = ref([]);
//选取在线图片的数组,返回给父组件使用
const fileListOnline = ref([]);


//初始化
onMounted( ()=>{
  getPictureArray();
})

/**
 * 文件上传错误时的方法
 */
const errorUpload = () => {
  showMessage("文件上传错误", "error");
}

/**
 * 文件上传成功后的钩子
 * @param response
 * @param uploadFile
 * @param uploadFiles
 */
const successUpload = (response, uploadFile, uploadFiles) => {
  // console.log(response, uploadFile, uploadFiles)
  if (response.code === 200) {
    showMessage(response.message, "success");
    fileListLocally.value.push(requestUrl+response.data.file);
  } else {
    proxy.$refs.clear.handleRemove(uploadFile);
    showMessage(response.message, "error");
  }
}

/**
 * 删除文件之前的钩子，需要在这里剔除将来给父组件的数据
 * @param uploadFile
 */
const beforeRemove = (uploadFile) => {
  //在这里遍历fileListLocally数组，看看是否有跟uploadFile.response.data.file重合的
  //因为我写后端的时候，上传成功后返回来的数据是不带服务端域名的，这里究竟该如何比对，请你根据后端的返回的数据修改
  const delUrl = requestUrl+uploadFile.response.data.file;
  fileListLocally.value = fileListLocally.value.filter(item => item !== delUrl);
}

/**
 * 禁用上传的判断
 * 使用该方法时发现一个问题，就是如果设置了disabled参数，就会导致删除不可用，故此使用下面goTooFar方法弹出提示
 * @type {ComputedRef<boolean|undefined>}
 */
const isUploadDisabled = computed(() => {
  // 如果文件数量达到限制，禁用上传
  if (fileList.value.length >= props.uploadLimit) {
    return true;
  }
});

/**
 * 超出文件最大上传数量时弹出提示
 */
const goTooFar = () => {
  showMessage(`最多上传${props.uploadLimit}张图片`, "error");
}

//后端返回的图片列表
const imageArray = ref([]);
/**
 * 选择图片
 * @param image
 */
const toggleSelect = (image) => {
  //判断是否超过了最大值
  if(fileListOnline.value.length >= props.uploadLimit && image.isSelected===false) {
    showMessage(`最多选择${props.uploadLimit}张图片`,'error');
    return;
  }
  image.isSelected = !image.isSelected;
  if (image.isSelected) {
    fileListOnline.value.push(image.src);
  } else {
    // 如果图片被取消选中，从fileListOnline数组中移除对应的src
    const index = fileListOnline.value.indexOf(image.src);
    if (index !== -1) {
      fileListOnline.value.splice(index, 1);
    }
  }
};
/**
 * 删除选中的图片
 * @param index
 */
const deleteImage = (index) => {
  imageArray.value.splice(index, 1);
  //你可以在这里请求你后端的删除接口
};

/**
 * 请求后端接口，获取已上传的文件列表
 * @returns {Promise<void>}
 */
const getPictureArray = async () =>{
  const res = {
    path: props.path,
  }
  const result = await getFileArray(res);
  if(result.data.code===200){
    const list = result.data.data.list;
    if(result.data.data.list.length > 0){
      //为后端返回数据添加isSelected与isShowMask字段，当然你可以选择在后端进行拼接
      imageArray.value = list.map(item => ({
        ...item,
        isSelected: false,
        isShowMask: false
      }));
    }
  }else{
    showMessage(result.data.message,"error");
  }
}

const emit = defineEmits(['confirm-selection']);
/**
 * 通知父组件
 * @param type locally或online
 */
const confirmSelection = (type) => {
  let selectedFiles;
  if (type === 'locally') {
    console.log("此时fileListLocally的值是",fileListLocally.value)
    selectedFiles = fileListLocally.value;
  } else {
    selectedFiles = fileListOnline.value;
  }
  emit('confirm-selection', selectedFiles);
};

</script>

<style scoped lang="scss">
.demo-tabs > .el-tabs__content {
  padding: 32px;
  color: #6b778c;
  font-size: 32px;
  font-weight: 600;
}

.com-box {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  user-select: none;
}

.button{
  width: 100%;
  padding: 10px 0;
  display: flex;
  flex-direction: row-reverse; /* 从右向左排列子元素 */
  align-items: center;
  text{
    margin: 0 15px 0 0;
  }
}

.picture-list {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  //border: 1px solid red
}

.picture-box {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: flex-start;
  height: 220px;
  overflow:auto;
}

.image-wrapper {
  position: relative;
  width: 100px;
  height: 100px;
  border: 2px solid #cccccc;
  cursor: pointer;
  &.selected {
    border: 2px solid #1094fa;
  }
}

.mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 20px;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  //justify-content: center;
  flex-direction: row-reverse; /* 从右向左排列子元素 */
  align-items: center;
  color: white;
  cursor: pointer;
}

.delete-icon {
  font-size: 16px;
}

.delete-icon:hover{
  color: #59c4fe;
}

.check-mark {
  position: absolute;
  bottom: 0;
  right: 0;
  color: #ffffff;
  background: #1094fa;
  font-size: 15px;
  width: 20px;
  height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-top-left-radius: 5px;
}
</style>